#pragma once

#include <iostream>

#include "util.hpp"

#include <pthread.h>
#include <pthread.h>

#include <mutex>

namespace Cloud{

#define CONFIG_FILE "./cloud.conf"

class Config{    
public:
    static Config *GetInstance(); // 获取单例
private:
    Config(); // 构造函数私有化 并且在构造函数中读取配置文件
    static std::mutex _mutex; // 互斥锁 - 搞定同步问题
    static Config *_instance; // 单例实例
private:
    int _hot_time; // 热点时间判断
    int _server_port; // 服务器监听端口
    std::string _download_prefix; // 下载url前缀路径
    std::string _packfile_suffix; // 压缩包后缀名称
    std::string _back_dir; // 备份文件存放目录
    std::string _pack_dir; // 压缩包文件存放目录
    std::string _server_ip; // IP地址
    std::string _backup_file; // 数据信息存放文件    
                              
    bool ReadConfigFile(); // 读取配置文件                          
                              
public:
    int GetHotTime(); // 获取热点时间
    int GetServerPort(); // 获取服务器监听端口
    std::string GetDownloadPrefix(); // 获取前置路径
    std::string GetPackFileSuffix(); // 获取压缩包
    std::string GetBackDir(); // 获取备份文件目录
    std::string GetPackDir(); // 获取压缩包文件目录
    std::string GetServerIP(); // 获取IP地址
    std::string GetBackupFile(); // 获取数据信息存放文件

}; // class Config

std::mutex Config::_mutex ; // 互斥锁 - 搞定同步问题
Config *Config::_instance = nullptr; // 单例实例


Config *Config::GetInstance(){
    if(_instance == nullptr){
        _mutex.lock();
        if(_instance == nullptr){
            _instance = new Config();
        }
        _mutex.unlock();
    }
    return _instance;
}

Config::Config(){
    ReadConfigFile();
}  


bool Config::ReadConfigFile(){
    
    FileUtil fu(CONFIG_FILE); // 实例化一个文件工具类
    std::string body; // 实例化一个 string 对象用于接收从配置文件中读取的数据
    if(!fu.GetContent(&body)){
        std::cerr<<"ReadConfigFile GetContent for CONFIT_FILE failed"<<std::endl;
        return false;
    } // 获取文件数据
                          
    Json::Value root;
    if(!JsonUtil::UnSerialize(body,&root)){
        std::cerr<<"ReadConfigFile Unserialize failed"<<std::endl;
        return false;
    } // 将配置文件读取并反序列化至 root 中

    // 将反序列化后的信息从 Value 对象传至雷内成员中
    _hot_time = root["hot_time"].asInt(); 
    _server_port = root["server_port"].asInt();
    _download_prefix = root["download_prefix"].asString();
    _packfile_suffix = root["packfile_suffix"].asString();
    _back_dir = root["back_dir"].asString();
    _pack_dir = root["pack_dir"].asString();
    _server_ip = root["server_ip"].asString();
    _backup_file = root["backup_file"].asString();
    return true;
}


int Config::GetHotTime(){
    return _hot_time;
}               

int Config::GetServerPort(){
    return _server_port;
}         

std::string Config::GetDownloadPrefix(){
    return _download_prefix;
}

std::string Config::GetPackFileSuffix(){
    return _packfile_suffix;
}

std::string Config::GetBackDir(){
    return _back_dir;
}

std::string Config::GetPackDir(){
    return _pack_dir;
}

std::string Config::GetServerIP(){
    return _server_ip;
}

std::string Config::GetBackupFile(){
    return _backup_file;
}

}// namespace Cloud
